﻿#region Imported Namespaces


using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

using MobilePal.State;


#endregion


namespace MobilePal.Views.ButtonsView
{
  [ApplicationView("Buttons View")]
  internal sealed partial class ButtonsView: UserControl, IView
  {
    #region Fields


    private readonly Dictionary<Activity, Switch> _switches = new Dictionary<Activity, Switch>();
    private Button _selectedButton;
    private ButtonsViewSettings _settings;

    private Color _buttonFocusedForeColor;
    private Color _buttonForeColor;
    private Color _buttonOnBackColor;
    private Color _buttonOffBackColor;
    private Color _buttonOnToggledBackColor;
    private Color _buttonOffToggledBackColor;
    private Color _panelBackColor;

    #endregion


    #region Constructors/Finalizers


    public ButtonsView()
    {
      InitializeComponent();
    }


    #endregion


    #region Nested type: Switch


    private sealed class Switch
    {
      #region Fields


      public Button ButtonOff;
      public Button ButtonOn;


      #endregion
    }


    #endregion


    #region Events


    public Activity SelectedActivity
    {
      get
      {
        if(_selectedButton != null)
        {
          return _selectedButton.Tag as Activity;
        }

        return null;
      }
    }

    /// <summary>
    /// Gets the menu.
    /// </summary>
    /// <value>The menu.</value>
    public List<MenuItem> MenuItems
    {
      get
      {
        return null;
      }
    }

    public event EventHandler<ActivityEventArgs> ActivitySelected;


    #endregion


    #region Methods


    /// <summary>
    /// Initializes the specified activity collection.
    /// </summary>
    /// <param name="activityCollection">The activity collection.</param>
    /// <param name="settings">The settings.</param>
    public void Initialize(ActivityCollection activityCollection, ActivityCategoryCollection categoryCollection, ViewSettings settings)
    {
      if (activityCollection == null)
      {
        return;
      }

      _settings = settings as ButtonsViewSettings ?? new ButtonsViewSettings();

      _buttonFocusedForeColor = ColorConverter.ConvertFrom(_settings.ButtonFocusedForeColor);
      _buttonForeColor = ColorConverter.ConvertFrom(_settings.ButtonForeColor);
      _buttonOnBackColor = ColorConverter.ConvertFrom(_settings.ButtonOnBackColor);
      _buttonOffBackColor = ColorConverter.ConvertFrom(_settings.ButtonOffBackColor);
      _buttonOnToggledBackColor = ColorConverter.ConvertFrom(_settings.ButtonOnToggledBackColor);
      _buttonOffToggledBackColor = ColorConverter.ConvertFrom(_settings.ButtonOffToggledBackColor);
      _panelBackColor = ColorConverter.ConvertFrom(_settings.PanelBackColor);

      BackColor = _panelBackColor;

      foreach (Activity activity in activityCollection)
      {
        //if (activity.IsInPlainList)
        {
          AddSwitch(activity);
        }
      }

      activityCollection.ActivityIsInProgressChanged += ActivityIsInProgressChanged;
    }


    public ViewSettings GetSettings()
    {
      return new ButtonsViewSettings();
    }


    private void ActivityIsInProgressChanged(object sender, ActivityEventArgs e)
    {
      UpdateButtonsState(e.Activity);
    }


    public void ToggleSelectedActivity()
    {
      foreach (KeyValuePair<Activity, Switch> dictionary in _switches)
      {
        if (dictionary.Value.ButtonOn.Focused)
        {
          OnButtonOnClick(dictionary.Value.ButtonOn, new EventArgs());
          break;
        }

        if (dictionary.Value.ButtonOff.Focused)
        {
          OnButtonOffClick(dictionary.Value.ButtonOff, new EventArgs());
          break;
        }
      }
    }


    private void AddSwitch(Activity activity)
    {
      int count = _switches.Count;
      int halfWidth = Width / 2;
      int yShift = count * 40 + 15;

      var buttonOn = new Button
                       {
                         ForeColor = _buttonForeColor,
                         Tag = activity,
                         TabIndex = count*2,
                         Size = new Size(halfWidth - 14, 30),
                         Location = new Point(7 + (_settings.BackOrder ? 0 : halfWidth), yShift),
                         Anchor = AnchorStyles.Top
                       };

      var buttonOff = new Button
                        {
                          ForeColor = _buttonForeColor,
                          Tag = activity,
                          TabIndex = count * 2 + 1,
                          Size = new Size(halfWidth - 14, 30),
                          Location = new Point(7 + (!_settings.BackOrder ? 0 : halfWidth), yShift),
                          Anchor = AnchorStyles.Top
                        };

      buttonOn.Click += OnButtonOnClick;
      buttonOff.Click += OnButtonOffClick;

      buttonOn.GotFocus += OnButtonGotFocus;
      buttonOn.LostFocus += OnButtonLostFocus;
      buttonOff.GotFocus += OnButtonGotFocus;
      buttonOff.LostFocus += OnButtonLostFocus;

      Controls.Add(buttonOn);
      Controls.Add(buttonOff);

      _switches.Add(activity, new Switch {ButtonOn = buttonOn, ButtonOff = buttonOff});

      UpdateButtonsState(activity);

      if (_selectedButton != null)
      {
        return;
      }

      if (activity.IsInProgress)
      {
        buttonOff.Focus();
        _selectedButton = buttonOff;
      }
      else
      {
        buttonOn.Focus();
        _selectedButton = buttonOn;
      }
    }


    private static void OnButtonOnClick(object sender, EventArgs eventArgs)
    {
      var button = (Button)sender;
      var activity = (Activity)button.Tag;

      activity.IsInProgress = !activity.IsInProgress;
    }


    private void UpdateButtonsState(Activity activity)
    {
      Button buttonOn = _switches[activity].ButtonOn;
      Button buttonOff = _switches[activity].ButtonOff;

      string.Format(_settings.NodesLabelFormat, activity.Name);

      if (activity.IsInProgress)
      {
        buttonOff.BackColor = _buttonOffToggledBackColor;
        buttonOff.Text = string.Format(_settings.InProgressNodesLabelFormat, activity.Name, activity.LastToggleTime);
        buttonOff.Enabled = true;
        buttonOff.Focus();

        buttonOn.Enabled = false;
        buttonOn.BackColor = _buttonOnBackColor;
        buttonOn.Text = string.Format(_settings.NodesLabelFormat, activity.Name, activity.LastToggleTime);
      }
      else
      {
        buttonOn.BackColor = _buttonOnToggledBackColor;
        buttonOn.Text = string.Format(_settings.NodesLabelFormat, activity.Name, activity.LastToggleTime);
        buttonOn.Enabled = true;
        buttonOn.Focus();

        buttonOff.Enabled = false;
        buttonOff.BackColor = _buttonOffBackColor;
        buttonOff.Text = string.Format(_settings.InProgressNodesLabelFormat, activity.Name, activity.LastToggleTime);
      }
    }


    private static void OnButtonOffClick(object sender, EventArgs eventArgs)
    {
      var button = (Button)sender;
      var activity = (Activity)button.Tag;

      activity.IsInProgress = !activity.IsInProgress;
    }


    private void OnButtonGotFocus(object sender, EventArgs eventArgs)
    {
      var button = (Button)sender;
      var activity = (Activity)button.Tag;

      button.ForeColor = _buttonFocusedForeColor;
      _selectedButton = button;

      if (ActivitySelected != null)
      {
        ActivitySelected(this, new ActivityEventArgs(activity));
      }
    }


    private void OnButtonLostFocus(object sender, EventArgs eventArgs)
    {
      var button = (Button)sender;

      button.ForeColor = _buttonForeColor;
    }


    protected override void OnGotFocus(EventArgs e)
    {
      base.OnGotFocus(e);

      if(_selectedButton != null)
      {
        _selectedButton.Focus();
      }
    }


    #endregion

    private void ButtonsView_Resize(object sender, EventArgs e)
    {
      foreach (KeyValuePair<Activity, Switch> keyValuePair in _switches)
      {
        int buttonWidth = Width / 2 - 14;
        keyValuePair.Value.ButtonOn.Width = buttonWidth;
        keyValuePair.Value.ButtonOff.Width = buttonWidth;

        if (_settings.BackOrder)
        {
          keyValuePair.Value.ButtonOff.Left = Width / 2 + 7;
          keyValuePair.Value.ButtonOn.Left = 7;
        }
        else
        {
          keyValuePair.Value.ButtonOn.Left = Width / 2 + 7;
          keyValuePair.Value.ButtonOff.Left = 7;
        }
      }
    }
  }
}